package controllers

import (
	"fmt"
	"github.com/goravel/framework/contracts/http"
	"github.com/goravel/framework/facades"
	"github.com/goravel/framework/support/carbon"
	httpfacade "github.com/hulutech-web/http_result"
	"github.com/spf13/cast"
	"goravel/app/models"
)

type MiniController struct {
	//Dependent services
}

func NewMiniController() *MiniController {
	return &MiniController{
		//Inject services
	}
}

func (r *MiniController) MiniOption(ctx http.Context) http.Response {
	db := facades.Orm().Query()
	kinds := []models.Kind{}
	execSql := `
        SELECT k.*
        FROM kinds k
        LEFT JOIN kinds sub_kinds ON k.id = sub_kinds.pid
        WHERE sub_kinds.id IS NULL and k.deleted_at is null;
    `
	facades.Orm().Query().Raw(execSql).Scan(&kinds)
	type UserReq struct {
		ID   int    `json:"id" form:"id"`
		Name string `json:"name" form:"name"`
	}

	parkings := []models.Parking{}
	db.Model(&models.Parking{}).Where("state=?", "空闲").Find(&parkings)

	return httpfacade.NewResult(ctx).Success("", map[string]interface{}{
		"kinds": kinds, "parkings": parkings,
	})
}

func (r *MiniController) MiniUserOption(ctx http.Context) http.Response {
	name := ctx.Request().Input("name")
	db := facades.Orm().Query()
	type UserReq struct {
		ID   int    `json:"id" form:"id"`
		Name string `json:"name" form:"name"`
	}
	var userReqs []UserReq
	sql := `
			SELECT u.id,u.name
			FROM users u
			JOIN role_user ru ON u.id = ru.user_id
			JOIN roles r ON ru.role_id = r.id
			WHERE r.value = 'employee_role' and u.name like ?;`

	db.Raw(sql, "%"+name+"%").Scan(&userReqs)
	return httpfacade.NewResult(ctx).Success("", userReqs)
}

func (r *MiniController) MiniServiceOption(ctx http.Context) http.Response {
	name := ctx.Request().Input("name")
	kind_id := ctx.Request().Input("kind_id")
	s_ids := []uint{}
	db := facades.Orm().Query()
	db.Model(&models.Manhour{}).Select("service_id").Where("kind_id=?", kind_id).Pluck("service_id", &s_ids)
	services := []models.Service{}
	if name == "" {
		db.Model(&models.Service{}).Where("id in ?", s_ids).Find(&services)
	} else {
		db.Model(&models.Service{}).Where("name like ?", "%"+name+"%").Where("id in ?", s_ids).Find(&services)
	}
	return httpfacade.NewResult(ctx).Success("", services)
}

func (r *MiniController) MiniUserExceptOption(ctx http.Context) http.Response {
	user_ids := ctx.Request().InputArray("user_ids")
	name := ctx.Request().Input("name")
	db := facades.Orm().Query()
	type UserReq struct {
		ID   int    `json:"id" form:"id"`
		Name string `json:"name" form:"name"`
	}
	user_idsInt := []int{}
	for _, uid := range user_ids {
		user_idsInt = append(user_idsInt, cast.ToInt(uid))
	}
	var userReqs []UserReq
	sql := buildUserQuerySQL(name, user_idsInt)

	db.Raw(sql).Scan(&userReqs)
	return httpfacade.NewResult(ctx).Success("", userReqs)
}

func buildUserQuerySQL(name string, user_ids []int) string {
	var idNotInCondition string
	if len(user_ids) > 0 {
		// 构建正确的id not in条件，直接使用id值，用逗号分隔
		idNotInCondition = " AND u.id NOT IN ("
		for i, id := range user_ids {
			if i > 0 {
				idNotInCondition += ", "
			}
			idNotInCondition += fmt.Sprintf("%d", id)
		}
		idNotInCondition += ")"
	}

	const userQuerySQL = `
        SELECT u.id,u.name
        FROM users u
        JOIN role_user ru ON u.id = ru.user_id
        JOIN roles r ON ru.role_id = r.id
        WHERE r.value = 'employee_role' and u.name like '%s' %s;`

	nameParam := "%" + name + "%"
	return fmt.Sprintf(userQuerySQL, nameParam, idNotInCondition)
}

func (r *MiniController) MiniServiceExceptOption(ctx http.Context) http.Response {
	name := ctx.Request().Input("name")
	kind_id := ctx.Request().InputInt("kind_id")
	service_ids := ctx.Request().InputArray("service_ids")
	ser_ids := []uint{}
	facades.Orm().Query().Model(&models.Manhour{}).Select("service_id").Where("kind_id=?", kind_id).Pluck("service_id", &ser_ids)
	db := facades.Orm().Query()
	services := []models.Service{}
	db.Model(&models.Service{}).Where("name like ?", "%"+name+"%").Where("id in ?", ser_ids).
		Where("id not in ?", service_ids).Find(&services)
	return httpfacade.NewResult(ctx).Success("", services)
}

func (r *MiniController) MiniRepairInfo(ctx http.Context) http.Response {
	user := models.User{}
	facades.Auth(ctx).User(&user)
	var distanceDay int64
	var repairCount int64
	var totalRepairCount int64
	//1-距离上次（时间）天
	//2-本年报修（x）次
	//3-累计报修(x)次
	db := facades.Orm().Query()
	repair := models.Repair{}
	db.Model(&models.Repair{}).Where("user_id=?", user.ID).Order("id desc").First(&repair)
	if repair.ID != 0 {
		inDays := repair.CreatedAt.DiffInDays(carbon.Now())
		distanceDay = inDays
	}
	currentYear := carbon.Now().Year()
	//格式化为字符串
	db.Model(&models.Repair{}).Where("user_id", user.ID).
		Where("DATE_FORMAT(created_at, '%Y') =?", currentYear).Count(&repairCount)
	//计算当前时间与repair.created_at的时间差，返回天数，使用carbon
	db.Model(&models.Repair{}).Where("user_id", user.ID).Count(&totalRepairCount)

	return httpfacade.NewResult(ctx).Success("", map[string]interface{}{
		"distanceDay":      distanceDay,
		"repairCount":      repairCount,
		"totalRepairCount": totalRepairCount,
	})
}
